package main

import (
	"context"
	"github.com/gin-gonic/gin"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"github.com/spf13/pflag"
	"github.com/spf13/viper"
	_ "github.com/spf13/viper/remote"
	"go.uber.org/zap"
	"log"
	"net/http"
	"time"
	"webook/ioc"
)

func main() {
	initViperWatch()
	initLogger()
	tpCancel := ioc.InitOTEL()
	defer func() {
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		tpCancel(ctx)
	}()

	//db := initDB()
	//redisCli := redis.NewClient(&redis.Options{
	//	Addr: config.Config.Redis.Addr,
	//})
	//server := initWebServer(redisCli)
	//codeSvc := initCodeSvc(redisCli)
	//initUser(server, redisCli, db, codeSvc)
	app := InitWebServer()
	initPrometheus()
	app.cron.Start()
	defer func() {
		// 等待定时任务退出
		<-app.cron.Stop().Done()
	}()
	server := app.server
	server.GET("/hello", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "hello 启动成功")
	})
	for _, c := range app.consumers {
		err := c.Start()
		if err != nil {
			panic(err)
		}
	}
	runErr := server.Run(":8080")
	if runErr != nil {
		panic(runErr)
	}
	//server := gin.Default()
	//server.GET("/hello", func(ctx *gin.Context) {
	//	ctx.String(http.StatusOK, "hello 启动成功")
	//})
	//runErr := server.Run(":8080")
	//if runErr != nil {
	//	panic(runErr)
	//}
}

func initViperWatch() {
	cfile := pflag.String("config",
		"config/dev.yaml", "配置文件路径")
	// 这一步之后，cfile 里面才有值
	pflag.Parse()
	//viper.Set("db.dsn", "localhost:3306")
	// 所有的默认值放好s
	viper.SetConfigType("yaml")
	viper.SetConfigFile(*cfile)
	viper.WatchConfig()
	// 读取配置
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
	val := viper.Get("test.key")
	log.Println(val)
}

func initPrometheus() {
	go func() {
		// 专门给 prometheus 用的端口
		http.Handle("/metrics", promhttp.Handler())
		http.ListenAndServe(":8081", nil)
	}()
}

func initViper() {
	viper.SetConfigName("dev")
	viper.SetConfigType("yaml")
	viper.AddConfigPath("config")
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
}
func initViperV1() {
	cfile := pflag.String("config", "config/dev.yaml", "配置文件路径")
	pflag.Parse()
	viper.SetConfigType("yaml")
	viper.SetConfigFile(*cfile)
	err := viper.ReadInConfig()
	if err != nil {
		panic(err)
	}
}
func initViperRemote() {
	//接入远程配置中心etcd
	err := viper.AddRemoteProvider("etcd3", "http://127.0.0.1:12379", "/webook")
	if err != nil {
		panic(err)
	}
	viper.SetConfigType("yaml")
	err = viper.ReadRemoteConfig()
	if err != nil {
		panic(err)
	}
}
func initLogger() {
	logger, err := zap.NewProduction()
	if err != nil {
		panic(err)
	}
	zap.ReplaceGlobals(logger)
}

//func initDB() *gorm.DB {
//	//db, openErr := gorm.Open(mysql.Open("root:root@tcp(localhost:13316)/webook"))
//	db, openErr := gorm.Open(mysql.Open(config.Config.DB.DSN))
//	if openErr != nil {
//		panic(openErr)
//	}
//	initErr := dao.InitTable(db)
//	if initErr != nil {
//		panic(openErr)
//	}
//	return db
//}
//func initWebServer(redisCli redis.Cmdable) *gin.Engine {
//	server := gin.Default()
//
//	//限流
//	server.Use(ratelimit.NewBuilder(redisCli, time.Second, 100).Build())
//	//解决跨域问题
//	server.Use(cors.New(cors.Config{
//		AllowCredentials: true,
//		AllowHeaders:     []string{"Content-Type", "Authorization"},
//		//允许前端访问后端响应里的头部
//		ExposeHeaders: []string{"X-Jwt-Token"},
//		AllowOriginFunc: func(origin string) bool {
//			if strings.HasPrefix(origin, "http://localhost") {
//				return true
//			}
//			return strings.Contains(origin, "you_company.com")
//		},
//		MaxAge: 12 * time.Hour,
//	}))
//	userJWT(server)
//	return server
//}
//func userJWT(server *gin.Engine) {
//	login := middleware.LoginJWTMiddlewareBuilder{}
//	server.Use(login.CheckLogin())
//}
//
//func useSession(server *gin.Engine) {
//	//login := &middleware.LoginMiddlewareBuilder{}
//	////store := cookie.NewStore([]byte("secret")) //存储数据的 也就是userId存在了哪里 这里直接存cookie里
//	//store, err := redis.NewStore(16, "tcp", ""+
//	//	"localhost:6379", "",
//	//	[]byte("%bUWoX;9M76Cxfnu#j+YZ03d1rFS2!5|"),
//	//	[]byte("N1y$boeT.Y0(u]U8L24s9xQ6_n^iXVI5"))
//	//if err != nil {
//	//	panic(err)
//	//}
//	//server.Use(sessions.Sessions("ssid", store), login.CheckLogin())
//}
//
//func initUser(server *gin.Engine, redisCli redis.Cmdable, db *gorm.DB, codeSvc *service.codeService) {
//	//限流
//	ud := dao.NewUserDAO(db)
//	uc := self_cache.NewUserCache(redisCli)
//	ur := repository.NewCacheUserRepository(ud, uc)
//	us := service.NewUserService(ur)
//	uh := web.NewUserHandler(us, codeSvc)
//	uh.RegisterRoutes(server)
//}
//func initCodeSvc(redisCli redis.Cmdable) *service.codeService {
//	cc := self_cache.NewCodeCache(redisCli)
//	repo := repository.NewCodeRepository(cc)
//	return service.NewCodeService(repo, initMemorySms())
//}
//func initMemorySms() sms.Service {
//	return local_sms.NewService()
//}
